package pri.zxx.learndemo.xmlpaser;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAliasType;
import org.apache.commons.lang3.StringUtils;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Objects;

public class XmlTransfer {
    /**
     * 将XML转为指定的POJO
     *
     * @param clazz
     * @param xmlStr
     * @return
     * @throws Exception
     */
    public static Object xmlStrToOject(Class<?> clazz, String xmlStr) throws Exception {
        Object xmlObject = null;
        Reader reader = null;
        JAXBContext context = JAXBContext.newInstance(clazz);
        // XML 转为对象的接口
        Unmarshaller unmarshaller = context.createUnmarshaller();
        reader = new StringReader(xmlStr);
        //以文件流的方式传入这个string
        xmlObject = unmarshaller.unmarshal(reader);
        if (null != reader) {
            reader.close();
        }
        return xmlObject;
    }

    public static <T> String objToxml(T obj) throws JAXBException {
        Writer writer = new StringWriter();

        JAXBContext jaxbContext = JAXBContext.newInstance(obj.getClass());
        Marshaller marshaller = jaxbContext.createMarshaller();
        marshaller.setProperty("jaxb.fragment", true);
        marshaller.setProperty("jaxb.formatted.output", Boolean.TRUE);
        marshaller.marshal(obj, writer);
        return writer.toString();
    }

    public static String objToXmlStream(AbstractXmlDto obj) {
        XStream xStream = new XStream();
        xStream.autodetectAnnotations(true);
        String s = xStream.toXML(obj);
        return s;
    }

    public static <T> T xmlToObjStream(Class<T> aClass, String xmlString) {
        XStream xs = new XStream();
        xs.allowTypes(new Class[]{aClass});
        xs.alias(aClass.getSimpleName(), aClass);
        XStreamAliasType declaredAnnotation = aClass.getAnnotation(XStreamAliasType.class);
        if (Objects.isNull(declaredAnnotation)) {
            declaredAnnotation = aClass.getSuperclass().getAnnotation(XStreamAliasType.class);
        }
        if (Objects.nonNull(declaredAnnotation)) {
            String value = declaredAnnotation.value();
            if (StringUtils.isNotEmpty(value)) {
                xs.aliasType(value, aClass);
            }
        }
        xs.ignoreUnknownElements();
        xs.autodetectAnnotations(true);
        return (T) xs.fromXML(xmlString.trim());
    }
}
